/**
 * 状态机 使用闭包实现
 */
const fileUtils = require('../utils/fileUtils')
module.exports = function StateMachine(applicationConfig) {
  let config, currentState, nextState, states
  let commonEngines = [], execEngines = []

  init(applicationConfig)

  function init(applicationConfig) {
    config = applicationConfig
    currentState = applicationConfig.currentState
    states = applicationConfig.states
    console.log('::状态机初始化参数完成::')
  }

  function run() {
    startCommonEngines()
    startStateEngines()
    console.log('::状态机已启动::')
    loop()
  }

  function startCommonEngines() {
    const commonModules = config.commonModules
    console.log('------', commonModules)
    for (let { moduleName, modulePath, priority, disable } of commonModules) {
      if (disable) {
        continue
      }
      console.log(`::载入common模块${moduleName}::`, modulePath, priority)
      const commonEngine = engines.execScript(moduleName, fileUtils.readFile(modulePath), {
        loopTimes: 9999,
        interval: priority
      })
      commonEngines.push(commonEngine)
    }
  }

  function startStateEngines() {
    const execModules = states[currentState].slots
    for (let { moduleName, modulePath, priority, disable } of execModules) {
      if (disable) {
        continue
      }
      console.log(`::载入state模块: ${moduleName}::`, modulePath, priority)
      const execEngine = engines.execScript(moduleName, fileUtils.readFile(modulePath), {
        loopTimes: 9999,
        interval: priority
      })
      execEngines.push(execEngine)
    }
  }
  function loop() {
    do {
      console.log('::状态机执行中::')
      // 这里为了节约性能, 可以设置较长的主线程休眠时间
      sleep(10000)
    }
    while (stateChangeCheck())
    destroy()
  }

  function destroy() {
    commonEngines = []
    execEngines = []
    console.log('::状态机停止运行::')
  }

  function stateChangeCheck() {
    // 找是否还有在运行的state脚本
    const runningEngine = execEngines.find(engine => !engine.getEngine().isDestroyed())
    // 没有则进行状态变更
    if(!runningEngine) {
      console.log('::状态机状态变更::', currentState, nextState)
      currentState = nextState
      if(!currentState) {
        return false
      }
      // 状态发生变更, 此时应该重新init stateEngines
      startStateEngines()
      return true
    }
  }

  return {
    run
  }
}
